//==============================================================================
//
//           DProperty - the property element in the ofc-library
//
//               Copyright (C) 2003  Dick van Oudheusden
//  
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//==============================================================================
// 
//  $Date: 2004-09-18 05:06:59 $ $Revision: 1.2 $
//
//==============================================================================

#include "ofc/DProperty.h"

#include "ofc/DTree.h"


#if _INTERFACE_


#include "ofc/config.h"

#include "ofc/DText.h"

#include "ofc/DParsable.h"
#include "ofc/DTextable.h"


//
// The DProperty class implements methods for storing properties. It also
// implements class methods for adding, removing, importing and exporting
// program wide properties. Every object in a program can use properties
// from a property file with this class.
// 

@interface DProperty : Object
{
@private
   DText                    *_name;   // the item: group or property
   id <DTextable,DParsable>  _value;  // the reference to the value 
}

#endif


@implementation DProperty


#if _PRIVATE

// All properties in the program

static DTree *_properties = nil;

//
// Add an property/group to the tree of properties
// 
// param parent    the parent property
// param property  the property to be added
// 
// return is the parent property found ?
// 

static BOOL addItem(DProperty *parent, DProperty *property)
{
}

#endif


//// Constructors

//
// Initialise an empty property
//
// @return the object
//

- (DProperty *) init
{
  [super init];

  _name    = nil;
  _value   = nil;
  
  return self;
}

//
// Initialise a property
// 
// @param name         the property name
// @param value        the reference to the value object
// 
// @return the object
// 

- (DProperty *) init :(const char *) name :(id <DTextable,DParsable>) value
{
  [self init];
  
  [self property :name :value];
  
  return self;
}

//
// Initialise a group of properties
// 
// @param name         the group name
// 
// @return the object
// 

- (DProperty *) init :(const char *) name
{
  [self init];
  
  [self group :name];

  return self;
}


//// Copy related methods

//
// Deepen a copy of the property
//
// @return the object
//

- deepen
{
  [super deepen];

  if (_name != nil)
    _name = [_name copy];

  return self;
}


//// Destructor

//
// Free the property
//
// @return the object
//

- free
{
  if (_name != nil)
    [_name free];
  
  _value = nil;
  
  return [super free];
}


//// Member methods

//
// Set the property name and reference object for the property
// 
// @param name         the property name
// @param value        the reference object
//
// @return the object
//

- (DProperty *) property :(const char *) name :(id <DTextable,DParsable>) value
{
  if ((name == NULL) || (*name == EOS))
  {
    WARNING(DW_INVALID_ARG, "name");
  }
  else if (value == nil)
  {
    WARNING(DW_NIL_NOT_ALLOWED, "value");
  }
  else
  {
    if (_name == nil)
      _name = [DText new];
    
    [_name set :name];
    
    _value = value;
  }
  
  return self;
}

//
// Set the group name for a property group
//  
// @param name      the name of the group
//
// @return the object
//

- (DProperty *) group :(const char *) name
{
  if ((name == NULL) || (*name == EOS))
  {
    WARNING(DW_INVALID_ARG, "name");
  }
  else
  {
    if (_name == nil)
      _name = [DText new];
    
    [_name set :name];
    
    _value = nil;
  }
  
  return self;
}

//
// Return the name (of the property of group)
// 
// @return the property name (or NULL)
// 

- (const char *) name
{
  return (_name != nil) ? [_name cstring] : NULL;
}

//
// Return the reference to the value object
// 
// @return the reference (or nil)
// 

- (id <DTextable,DParsable>) value
{
  return _value;
}


//// Main class method

//
// Add a group property to the program wide tree of properties
//
// @param parent   the parent (group) property 
// @param name     the group name
//
// @return the (new) group property
//

+ (DProperty *) addGroup :(DProperty *) parent :(const char *) name
{
  DProperty *property = [DProperty alloc];
  
  [property init :name];
  
  //Todo: addItem(parent, property);
  
  return property;
}

//
// Add a property to the program wide tree of properties
// 
// @param parent   the parent (group) property
// @param name     the property name
// @param value    the reference to the value object
// 
// @return th (new) property
// 

+ (DProperty *) addProperty :(DProperty *)              parent 
                            :(const char *)             name
                            :(id <DTextable,DParsable>) value
{
  DProperty *property = [DProperty alloc];
  
  [property init :name :value];
  
  //addItem(parent, property);
  
  return property;
}

//
// Import the properties
// 
// @param name     the name of the program, properties file etc
// 
// @return success
// 

+ (BOOL) importProperties :(const char *) name
{
  BOOL ok = NO;
  
  if ((name == NULL) || (*name == EOS))
  {
    WARNING(DW_INVALID_ARG, "name");
  }
  else
  {
  }
  
  return ok;
}
    
//
// Export the properties
// 
// @param name     the name of the program, the properties file etc.
// 
// @return success
// 

- (BOOL) exportProperties :(const char *) name
{
  BOOL ok = NO;
  
  if ((name == NULL) || (*name == EOS))
  {
    WARNING(DW_INVALID_ARG, "name");
  }
  else
  {
  }
  
  return ok;
}

//
// Remove a property from the tree of program wide properties
// 
// @param property   the property to be removed (and FREED)
// 
// @return success (property is only freed by success)
// 

+ (BOOL) removeProperty :(DProperty *) property
{
  BOOL ok = YES;
  
  if (property != nil)
  {
    //if (removeItem(property))
    //{
    //  [property free];
    //}
    //else
    //{
    //  ok = NO;
    //}
  }
  
  return ok;
}

//
// Remove a property from the tree of program wide properties
// 
// @param parent   the parent (group) property
// @param name     the name of the property
// 
// @return success (property is freed if succesfull)
// 

+ (BOOL) removeProperty :(DProperty *) parent :(const char *) name
{
  BOOL ok = NO;
  
  if ((name == NULL) || (*name == EOS))
  {
    WARNING(DW_INVALID_ARG, "name");
  }
  else
  {
    DProperty *property = nil; //findProperty(parent, name);
    
    if (property != nil)
    {
      //if (removeItem(property))
      //{ 
      //  [property free];
      //  ok = YES;
      //}
    }
  }
  
  return ok;
}

@end

/*==========================================================================*/
